Common Mistakes
目录
- Common Ebuild Writing Mistakes
- Invalid use of
static
use-flag - Invalid use of ROOT
- 引用可以压缩的文档的完整路径
- Build log not verbose
- -Werror compiler flag not removed
- Missing/Invalid/Broken Header
- Redefined P, PV, PN, PF
- Including version numbers in SRC_URI and S
- DEPEND has syntactical errors
- DEPEND is incomplete
- LICENSE Invalid
- Untested ARCHs in KEYWORDS
- SLOT missing
- DESCRIPTION and HOMEPAGE wrong
- Wrongfully used spaces instead of TABS
- Trailing whitespace
- 添加多余的
S=${WORKDIR}/${P}
- Documentation missing
- Masking unsupported/broken USE flags
- Invalid use of
- Common Ebuild Submission Mistakes
本章节包含有关开发人员在编写 ebuild 时犯的常见错误的资料。
Common Ebuild Writing Mistakes
Invalid use of static
use-flag
static
use-flag 应该仅用于使二进制文件静态链接而不是动态链接。它不应该用于使一个库安装静态库。相反, static-libs
use-flag 应该用于此目的。
Invalid use of ROOT
ROOT
的使用仅旨在影响软件包的安装方式(即安装到 ROOT
) —— 构建和编译不应该依赖于 ROOT
。因此不允许在 src_*
函数中使用 ROOT
。
也请见ROOT。
引用可以压缩的文档的完整路径
当向用户打印在那里可以找到诸如 INSTALL 值文件的文件时,不要指定完整路径因为=PORTAGE_COMPRELESS=会起作用。文件可能会会被用 gzip、bzip2 或其他压缩工具压缩。因此,不要这样做:
elog "They are listed in /usr/share/doc/${PF}/INSTALL.gz"
而要像这样做:
elog "They are listed in the INSTALL file in /usr/share/doc/${PF}"
Build log not verbose
当编写 ebuild 时,你应该总是检查构建日志,因为构建系统可能会葫芦俄 CC/CXX/LD/CFLAGS/LDFAGS 都能或默认添加不需要的 flag。为了分析此问题并获得完整的信息,以防有人报告你的软件包存在漏洞, 构建日志必须总是详细的 。
根据构建系统,有几个方法来修复构建日志不详细的问题:
对于基于 cmake
的构建系统,ebuild 只要调用 cmake-utils_src_compile 即可,默认情况下该函数会拾取 camke-utils.eclass 变量 CMAKE_VERBOSE=1
。如果你出于任何原因直接调用 emake,那可以执行 emake VERBOSE=1
(注意,cmake-utils_src_compile 也接受传递给 make 的参数)。
对于基于 autotools
的构建系统你可以传递 --disable-silent-rules
到 econf,或使用自动传递该参数的 EAPI 5。 emake -V1
也有同样的效果。
对于自定义的 Makefile,你通常必须编写一个 patch。尝试向上游添加诸如=V=1=之类的选项以开启完整详细信息。
Note:如果你遇到受影响的软件包或 eclass,其使用的构建系统无法被 portage 控制,你应该提交 bug(与 patch 一起更好)并且使它屏蔽 bug #429308。ebuild 级别之上的解决方案是首选。
-Werror compiler flag not removed
-Werror
flag 将所有的警告变成错误,所以如果遇到任何警告会停止编译。
基本原理
该 flag 对 release 并不推荐并且在构建日志中遇到时总是应该禁用的,因为在很多情况下这种破坏都是无目的的,例如:
- 在 GCC/GLIBC 版本 bump 时出现新的警告,开发人员在编码时尚未意识到
- 一些 autoconf 检查将会严重失败
- 库添加已弃用 API 的警告,尽管该 API 仍在工作/受支持
- 在鲜为人知的架构上,我们可能会比在普通架构上得道不同/更多的警告
- 随机破坏取决于开发人员在哪个发行版/架构/库版本/内核/用户空间测试
-Werror
关闭 -Werror
我们仍可见到警告,但没有理由它们会造成编译失败。还请注意,portage 已经发出了有关可能会造成运行时损坏的 gcc 警告的 QA notices。
如何修复
你应该使用如下方法修复受影响的构建系统:
- 从构建系统中移除编译 flag,例如 Makefile.am 或 configure.ac 或甚至提供开关(对于基于 autotools 的构建系统可能是
--disable-werror
,其非常适合向上游发送 patch) - 使用 append-flags -Wno-error(需要 flag-o-matic.eclass);为此环境 flag 必须尊重并放在构建系统 flag 之后;该方法不是首选,因为它将同时禁用所有
-Werror=specific-warning
flag,请见下一节
始终检查构建日志中真的没有该 flag。
Specific -Werror=… flags
GCC 可以使任何指定警告变成错误。例如一个指定的-Werror flag 可以是 -Werror=implicit-function-declaration
,并将仅影响关于隐式函数声明的警告。保留这些鸳鸯是最安全的,因为将它们固定在此问题上,并且不会造成随机的构建时间破坏。还有,我们可以期望上游这么做是为了避免已知的运行时错误,而不仅仅是测试其构建。然而你应该自己检查指定的警告,或在不确定时询问其他开发人员。
例外情况
从 configure.ac 中删除 -Werror
会在极少数的情况下(其中配置阶段依赖于退出代码)导致中断。见app-emulation/open-vm-tools bug。但是即使如此,我们仍将其从生成的 Makefile 中删除。
Missing/Invalid/Broken Header
当你提交 ebuild 时,header 必须和skel.ebuild中的完全形同。
前两行必须如下所示:
# Copyright 1999-2020 Gentoo Authors # Distributed under the terms of the GNU General Public License v2
Note:header 以前包括带有一个 CVS
$Id$
或$Header$
关键字的第三行。这一行在转为 git 后废除了,其由decision of the Gentoo Council on 28 February 2017决定并不能再继续添加。
Redefined P, PV, PN, PF
你应该永远不重新定义这些变量。总是使用 MY_P、MY_PN、MY_PV、P0 等。有关更多信息,请见再 portage 其他这样做的 ebuild。大多数 ebuild 使用 bash 的"Parameter Expansion"。请阅读 bash 的 man page 以理解"Parameter Expansion"是怎么样工作的。
顺便,如果你找到重新定义这些变量的软件包,请不要复制它。提交有关该 ebuild 的 bug。
Including version numbers in SRC_URI and S
你应该尽量不要再 SRC_URI 和 S 中包含版本号。总是尝试使用 ${PV}
或 ${P}
。这会使得维护 ebuild 更加容易。如果版本号与压缩包/源代码的名字不是一致,则使用 MY_P。一个例子是 dev-python/pyopenal 拉取一个名为 PyOpenAL 的压缩包,所以我们可以像这样重新定义:
MY_P=${P/pyopenal/PyOpenAL} SRC_URI="http://download.gna.org/pyopenal/${MY_P}.tar.gz" S=${WORKDIR}/${MY_P}
DEPEND has syntactical errors
用户提交的 DEPEND 和 RDEPEND 字段可能会出现很多错误。在编写依赖的时候,需要注意以下几点。
- 总是包括 CATEGORY。例如,使用
>=x11-libs/gtk+-2
,而不是>=gtk+2
。 - 不要在>=依赖项添加星号(*)。例如,应该使用
>=x11-libs/gtk+-2
,而不是>=x11-libs/gtk+-2*
。 - 指定 GTK。对于 GTK+1 的应用,总是使用
=x11-libs/gtk+-1.2*
。 - 永远不要依赖 meta 包。所以,不要依赖于 gnome-base/gnome,总是依赖于指定的库,像 libgnome。
- 一行一个依赖项。不要把多个依赖项放到同一行。这会使阅读变得难看并且难以遵循。
DEPEND is incomplete
这是另一个非常常见的错误。ebuild 提交者提交“可以正常工作”的 ebuild,而不检查依赖是否正确。这里有一些如何找到正确依赖的提示。
- 查看
configure.in
或configure.ac
。在此处查找软件包的检查。需要注意的是 pkg-config 的检查或检查特定版本的 AM_*函数。 - 查看包含的.spec 文件。一个好的依赖关系指示是查看其中包含的.spec 文件以获取相关的依赖。然而,不要相信它们是绝对完整的依赖关系列表。
- 查看应用程序/库的网站。检查应用程序的网站,以了解他们建议的可能的依赖关系。
- 阅读软件包的 README 和 INSTALL。它们通常包含关于构建和安装软件包的有用信息。
- 记住非二进制依赖,如 pkg-config、文档生成程序等。通常构建过程要求一些依赖,像 inittool、libtool、pkg-config、doxygen、scrollkeeper、gtk-doc 等。确保明确说明这些内容。
LICENSE Invalid
另一个用户犯的常见错误是当提交 ebuild 时提供了无效的 license。例如, GPL
不是一个有效的 license。你需要指定 GPL-1
或 GPL-2
。 LGPL
也是同样的情况。确保你在 LICENSE
字段中使用的 license 在 licenses
目录下存在。一个提示,检查源代码压缩文件中的 COPYING
文件以获取许可证。如果软件包没有指定使用 GPL-1
或 GPL-2
,软件包很有可能使用 GPL-2
。
如果你提交的软件包 license 是独一无二的并且不在 licenses/
中,那么你必须在单独的文件中提交新的许可证。
Untested ARCHs in KEYWORDS
请不要添加其他的 ARCH 到 KEYWORDS 中,除非 ebuld 在该 ARCH 上经过了测试。还有所有新的 ebuild 应该使用 ~x86 或无论架构是什么。确保当你 bump 版本时,稳定(?)的 KEYWORDS 全部标记为~。
SLOT missing
确保在 ebuild 中又 SLOT 变量。如果你不打算使用它,也不要将其删除。设为:
SLOT="0"
DESCRIPTION and HOMEPAGE wrong
请检查 HOMEPAGE
变量是否正确,并且如果用户想了解有关软件包的更多信息,引导用户进入正确的页面。确保 DESCRIPTION
不会太长。好的描述将在一句话内描述软件包的主要功能。如果软件包没有 homepage 可用,则设置 HOMEPAGE
变量为 https://wiki.gentoo.org/wiki/No_homepage
。
Wrongfully used spaces instead of TABS
因为提交者没有遵循使用 TABS 而不是空格的方针,而重新格式化 ebuild 的每一行并不有趣。所有请使用 tabs。
Trailing whitespace
我经常对此感到内疚。记住在你的 build 上运行 repoman,它可以告诉你在行尾是否有空白或者是否有空行。
添加多余的 S=${WORKDIR}/${P}
如果 S=${WORKDIR}/${P}
,那么不应该将其添加到你的 ebuild 中。这已经默认设置了,你应该仅在其值与 ${WORKDIR}/${P}
不同时才添加它。
Documentation missing
如果你的软件包有文档,确保使用 dodoc
安装或安装到 /usr/share/doc/${PF}
。到运行 dodoc
/ doins
时检查错误。
如果软件包的文档非常大或需要额外的依赖来构建,你应该用 doc
USE flag 使它成为可选的。如果文档很小并且不需要额外的依赖(例如 README
文件),那么应无条件的安装它。
Masking unsupported/broken USE flags
异常情况下,软件包可能具有不支持/损坏的 USE flag(这可能发生在原生或 custom-cflags 上)。那么该 USE flag 必须在该 ebuild 中屏蔽(通常在 profile/base/package.use.mask),至少当 ebuild 到达稳定分支时。
Common Ebuild Submission Mistakes
Introduction
请根据Adding a New Ebuild教程正确提交 ebuild。
Tarball'ing an ebuild
请不要把 ebuild 或 patch 作为 tarball 附加。以避免 review 时的额外操作。
Inlining Ebuilds
不要将 ebuild 剪切并粘贴到 bugzilla 的注释字段中。
No description on what the package is
请让我们知道这是什么软件包,并填写应用程序的主页(如果有)的 URL。
更新软件包但不说明更改的内容
如果你提交了软件包的更新,那么确保你解释了在 ebuild 中做了什么更改。例如,如果软件包引入了一个新的特性/功能并且你使用了 USE flag, 将它列在你的 bug 中。不要让我们因此受伤。
提交 diff 而不是整个 ebuild 来更新软件包时明智的。生成它的最佳方法时:
$ diff -u some-package-0.1.0.ebuild some-package-0.2.0.ebuild > ~/some-package-0.2.0.diff
因版本 bump 提交未更改的 ebuild
如果你提交一个新版本的软件包到 portage 中,确保存在的 ebuild 正常工作并且确保更改已合并到新的 build 中(例如添加文档)。如果对闲钱版本的 ebuild 不需要进行任何更改,那么请不要附加 ebuild。只要在 bug report 中说明你复制了 ebuild 并验证了该软件包可以正常安装和工作。